﻿/*
 * Tencent is pleased to support the open source community by making xLua available.
 * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
 * http://opensource.org/licenses/MIT
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using XLua;
using System;
using XLua.LuaDLL;

public class UpdateBehaviour : MonoBehaviour
{
    public static UpdateBehaviour Instance = null;

    private Action<LuaTable> luaStart = null;
    private Action<LuaTable> luaUpdate = null;
    private Action<LuaTable> luaOnDestroy = null;
    private Action<LuaTable> luaAwake = null;
    private Action<LuaTable> luaOnEnable = null;
    private Action<LuaTable> luaOnDisable = null;
    private Action<LuaTable, LuaTable> luaAddBehaviour = null;
    private Action<LuaTable, LuaTable> luaRemoveBehaviour = null;
    private LuaTable scriptEnv = null;

    public static void AddUpdateScript(XLua.LuaTable luaScript)
    {
        if (Instance != null)
        {
            Instance.AddBehaviour(luaScript);
        }
    }

    public static void RemoveUpdateScript(LuaTable luaScript)
    {
        if (Instance != null)
        {
            Instance.RemoveBehaviour(luaScript);
        }
    }

    void Awake()
    {
        if (Instance == null)
        {
            DontDestroyOnLoad(this);
            Instance = this;
        }
    }

    // 外部设置lua脚本
    public void SetScriptEnv(LuaTable env)
    {
        if (env == null)
        {
            return;
        }
        scriptEnv = env;
        BindScriptEnvParam();
        if (luaAwake != null)
        {
            luaAwake(scriptEnv);
        }
    }

    // 绑定脚本参数
    private void BindScriptEnvParam()
    {
        if (scriptEnv == null)
        {
            return;
        }
        scriptEnv.Set("gameObject", gameObject);
        scriptEnv.Set("transform", transform);
        scriptEnv.Get("awake", out luaAwake);
        scriptEnv.Get("start", out luaStart);
        scriptEnv.Get("update", out luaUpdate);
        scriptEnv.Get("onDestroy", out luaOnDestroy);
        scriptEnv.Get("onEnable", out luaOnEnable);
        scriptEnv.Get("onDisable", out luaOnDisable);
        scriptEnv.Get("addBehaviour", out luaAddBehaviour);
        scriptEnv.Get("removeBehaviour", out luaRemoveBehaviour);
    }

    public LuaTable GetScriptEnv()
    {
        return scriptEnv;
    }

    // Use this for initialization
    void Start()
    {
        if (luaStart != null)
        {
            luaStart(scriptEnv);
        }
    }

    private void OnEnable()
    {
        if (luaOnEnable != null)
        {
            luaOnEnable(scriptEnv);
        }
    }

    private void OnDisable()
    {
        if (luaOnDisable != null)
        {
            luaOnDisable(scriptEnv);
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (luaUpdate != null)
        {
            luaUpdate(scriptEnv);
        }
    }

    void OnDestroy()
    {
        if (luaOnDestroy != null)
        {
            luaOnDestroy(scriptEnv);
        }
        luaOnDestroy = null;
        luaUpdate = null;
        luaStart = null;
        if (scriptEnv != null)
        {
            scriptEnv.Dispose();
            scriptEnv = null;
        }
    }

    private void AddBehaviour(XLua.LuaTable luaTable)
    {
        if (luaAddBehaviour != null)
        {
            luaAddBehaviour(scriptEnv, luaTable);
        }
    }
    
    private void RemoveBehaviour(XLua.LuaTable luaTable)
    {
        if (luaRemoveBehaviour != null)
        {
            luaRemoveBehaviour(scriptEnv, luaTable);
        }
    }

   private void OnApplicationQuit()
    {
        Action<LuaTable> appout = null;
        scriptEnv.Get("onApplicationQuit", out appout);
        if (appout!=null)
        {
            appout(scriptEnv);
        }
    }
}
